/*
 *
 *  *    Copyright 2020-2021 Luter.me
 *  *
 *  *    Licensed under the Apache License, Version 2.0 (the "License");
 *  *    you may not use this file except in compliance with the License.
 *  *    You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  *    Unless required by applicable law or agreed to in writing, software
 *  *    distributed under the License is distributed on an "AS IS" BASIS,
 *  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  *    See the License for the specific language governing permissions and
 *  *    limitations under the License.
 *
 */

package com.luter.heimdall.core.authorization.store;

import com.luter.heimdall.core.authorization.authority.GrantedAuthority;
import com.luter.heimdall.core.authorization.provider.AuthorityDataProvider;
import com.luter.heimdall.core.details.UserDetails;

import java.util.List;
import java.util.Map;

/**
 * 权限存储
 * <p>
 * 缓存 应用权限 和 用户权限，用作授权判断
 * <p>
 * <p>
 * 实现了类似二级缓存的功能，当用户访问需要授权资源的时候，
 * <p>
 * 会首先从缓存中获取权限数据，如果不存在或者为空，
 * <p>
 * 则从数据提供者服务获取
 * <p>
 * 获取成功后，存入缓存，继续权限判断流程
 *
 * @author luter
 * @see AuthorityDataProvider#loadAppAuthorities(String)
 * @see AuthorityDataProvider#loadUserAuthorities(UserDetails)
 */
public interface AuthorizationStore {
    /**
     * 是否支持到期自动清理
     * <p>
     * 比如 redis 的 ttl 机制
     * <p>
     * 这个方法用作定时清理任务判断是否需要执行，
     * 对于不具备自动到期删除的缓存，定时任务会定期清理数据。
     *
     * @return the cache type enum
     */
    boolean isSelfExpired();

    /**
     * 获取用户权限
     *
     * @param userDetails the user details
     * @return the user authorities
     */
    List<? extends GrantedAuthority> getUserAuthorities(UserDetails userDetails);

    /**
     * 存入用户权限
     *
     * @param principal   the principal
     * @param authorities the authorities
     */
    void putUserAuthorities(String principal, List<? extends GrantedAuthority> authorities);

    /**
     * 删除用户权限
     *
     * @param userDetails the user details
     */
    void removeUserAuthorities(UserDetails userDetails);

    /**
     * 删除用户权限
     * <p>
     * 删除后，下次访问授权资源，系统会自动从外部数据服务重新加载此用户的权限资源
     *
     * @param appId  the app id
     * @param userId the user id
     */
    void removeUserAuthorities(String appId, String userId);

    /**
     * 删除所有应用的所有用户的权限缓存，大操作，慎用
     * <p>
     * 删除后，下次访问授权资源，系统会自动从外部数据服务重新加载用户的权限资源
     */
    void removeAllUserAuthorities();

    //////APP权限

    /**
     * 获取应用权限
     *
     * @param appId the app id
     * @return the sys authorities
     */
    Map<String, List<String>> getAppAuthorities(String appId);

    /**
     * 获取应用权限
     *
     * @param userDetails the user details
     * @return the sys authorities
     */
    Map<String, List<String>> getAppAuthorities(UserDetails userDetails);

    /**
     * 存入应用权限
     *
     * @param appId       the app id
     * @param authorities the authorities
     */
    void putAppAuthorities(String appId, Map<String, List<String>> authorities);

    /**
     * 删除应用权限
     * <p>
     * <p>
     * 删除后，下次访问授权资源，系统会自动从外部数据服务重新加载此应用的权限资源
     *
     * @param appId the app id
     */
    void removeAppAuthorities(String appId);

    /**
     * 删除系统权限
     * <p>
     * <p>
     * 删除后，下次访问授权资源，系统会自动从外部数据服务重新加载此应用的权限资源
     *
     * @param userDetails the user details
     */
    void removeAppAuthorities(UserDetails userDetails);

    /**
     * 删除所有应用的权限缓存，大操作，慎用
     * <p>
     * 删除后，下次访问授权资源，系统会自动从外部数据服务重新加载应用系统权限资源
     */
    void removeAllAppAuthorities();

}
